package it.antonio.ilpizze.db.core.perst;

import it.antonio.ilpizze.db.DbException;
import it.antonio.ilpizze.db.core.Types;
import it.antonio.ilpizze.db.index.utils.FPerst;
import it.antonio.ilpizze.db.io.IOConstants;
import it.antonio.ilpizze.db.io.IOFile;

public class ObjectPerst<K> implements FPerst<K>, IOConstants {
	
	@Override
	public long space() {
		return 35;
	}

	private void advance(IOFile file, int size) {
		file.position(file.position() + size);
	}

	@Override
	public void persist(IOFile file, K value) {
		if (value == null) {
			file.writeBoolean(true);
			advance(file, 34);
			return;
		}
		file.writeBoolean(false);

		int size = Types.size(value);
		if(size > 35 - SIZE_BOOLEAN - SIZE_BYTE) throw new DbException("Value to long for Index");
		
		Types type = Types.decode(value);
		
		file.writeByte(type.typeByte());
		type.write(file, value);
		
		advance(file, 35 - SIZE_BOOLEAN - SIZE_BYTE - size);// 35 - ISNULL - TYPE_BYTE - SIZE
	}

	@Override
	@SuppressWarnings("unchecked")
	public K read(IOFile file) {
		boolean isNull = file.readBoolean();
		if (isNull) {
			advance(file, 34);
			return null;
		}
		
		byte typeByte = file.readByte();
		Types type = Types.decode(typeByte);
		
		Object value = type.read(file);
		
		int size = Types.size(value);
		advance(file, 35 - SIZE_BOOLEAN - SIZE_BYTE - size);// 35 - ISNULL - TYPE_BYTE - SIZE
		
		return (K) value;
		
	}

}